package main

import (
	"image"
	"log"
	"time"
)

func main() {
	r := newRoverDriver()
	r.left()
	time.Sleep(3 * time.Second)
	r.right()
	time.Sleep(3 * time.Second)
	r.upper()
	time.Sleep(3 * time.Second)
	r.down()
	time.Sleep(3 * time.Second)
}

type command int

func (c command) String() (result string) {
	if c == 0 {
		result = "右"
	} else if c == 1 {
		result = "左"
	} else if c == 2 {
		result = "上"
	} else if c == 3 {
		result = "下"
	}

	return result
}

const (
	right = command(0)
	left  = command(1)
	upper = command(2)
	down  = command(3)
)

type roverDriver struct {
	commandc chan command
}

func newRoverDriver() *roverDriver {
	r := &roverDriver{
		commandc: make(chan command),
	}

	go r.dirve()
	return r
}

func (r *roverDriver) dirve() {
	pos := image.Point{X: 0, Y: 0}
	direction := image.Point{X: 1, Y: 0}

	updateInterval := 250 * time.Millisecond
	nextMove := time.After(time.Second)

	for {
		select {
		case cval := <-r.commandc:
			switch cval {
			case right:
				direction = image.Point{X: +1, Y: 0}
			case left:
				direction = image.Point{X: -1, Y: 0}
			case upper:
				direction = image.Point{X: 0, Y: +1}
			case down:
				direction = image.Point{X: 0, Y: -1}
			}
			log.Printf("new direction %v ,cval=%v", direction, cval)
		case <-nextMove:
			pos = pos.Add(direction)
			log.Printf("moved to %v", pos)
			nextMove = time.After(updateInterval)
		}
	}
}

func (r *roverDriver) left() {
	r.commandc <- left
}

func (r *roverDriver) right() {
	r.commandc <- right
}
func (r *roverDriver) upper() {
	r.commandc <- upper
}

func (r *roverDriver) down() {
	r.commandc <- down
}
